package com.qidian.blog.service.impl;

import com.qidian.blog.factory.MapperFactory;
import com.qidian.blog.factory.ServiceFactory;
import com.qidian.blog.mapper.BlogArticleMapper;
import com.qidian.blog.pojo.*;
import com.qidian.blog.service.BlogArticleService;
import com.qidian.blog.util.JudgeTools;
import com.qidian.blog.util.RedisTool;
import com.qidian.blog.util.ThreadStorage;
import com.qidian.blog.util.pojo.LayuiTableDTO;
import com.qidian.blog.util.pojo.QDResult;
import org.apache.ibatis.session.SqlSession;
import redis.clients.jedis.Jedis;

import java.util.*;

/**
 * @Author 郭浩
 * @Date 2022/10/11 16:17
 */
public class BlogArticleServiceImpl implements BlogArticleService {
    private BlogArticleMapper mapper = MapperFactory.getMapper(BlogArticleMapper.class);
    public List<BlogArticle> queryAll() {
        return mapper.queryAll();
    }

    @Override
    public QDResult save(BlogArticle article, BlogArticleContent content) {
        SqlSession sqlSession = MapperFactory.getSqlSession();
        BlogArticleMapper mapper = sqlSession.getMapper(BlogArticleMapper.class);
        try {
            if(mapper.save(article)==1){// 保存article
                // 设置content的id
                content.setArticleId(article.getArticleId());
                // 保存content
                mapper.saveContent(content);
                // 这里保存标签和文章的关系
                List<BlogTag> tags = article.getTags();
                if(tags!=null && tags.size() > 0){
                    for (BlogTag tag : tags){
                        mapper.saveTagsForArticle(article.getArticleId(),tag.getTagId());
                    }
                }
                // 提交事务
                sqlSession.commit();
                return QDResult.ok();
            }
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        }
        return QDResult.fal();
    }

    @Override
    public LayuiTableDTO<BlogArticle> queryByPage(int page, int limit, BlogArticle article, String timeStart, String timeEnd) {
        LayuiTableDTO<BlogArticle> dto = new LayuiTableDTO<>();
        dto.setCode(0);
        dto.setMsg("");
        dto.setCount(mapper.count(article,timeStart,timeEnd));
        dto.setData(mapper.queryByPage((page-1)*limit,limit,article,timeStart,timeEnd));
        return dto;
    }

    @Override
    public QDResult queryById(Long id) {
        return QDResult.ok(mapper.queryById(id));
    }

    @Override
    public QDResult detail(Long articleId, String token) {
        Jedis jedis = RedisTool.getResource();
        BlogArticle article = mapper.queryById(articleId);
        if (JudgeTools.isNull(token)){
            token = UUID.randomUUID().toString().replace("-","");
        }
        String key = "VIEWS-"+token;
        List<String> ids = null;
        if (!jedis.exists(key)||!(ids = jedis.lrange(key,0,-1)).contains(articleId + "")){
            article.setViews(article.getViews()+1);
            mapper.update(article);
            jedis.lpush(key,articleId+"");
            Date now = new Date();
            Calendar c = Calendar.getInstance();
            c.set(Calendar.HOUR_OF_DAY,23);
            c.set(Calendar.MINUTE,59);
            c.set(Calendar.SECOND,59);
            jedis.expire(key,(int)((c.getTimeInMillis()-now.getTime()/1000)));
        }
        jedis.close();
        return QDResult.ok(token,article);
    }

    public QDResult doPraise(Long articleId, String token) {
        Jedis jedis = RedisTool.getResource();
        BlogArticle article = mapper.queryById(articleId);
        if (JudgeTools.isNull(token)){
            token = UUID.randomUUID().toString().replace("-","");
        }
        String key = "LIKES-"+token;
        List<String> ids = null;
        if (!jedis.exists(key)||!(ids = jedis.lrange(key,0,-1)).contains(articleId + "")){
            article.setLikes(article.getLikes()+1);
            mapper.update(article);
            jedis.lpush(key,articleId+"");
            Date now = new Date();
            Calendar c = Calendar.getInstance();
            c.set(Calendar.HOUR_OF_DAY,23);
            c.set(Calendar.MINUTE,59);
            c.set(Calendar.SECOND,59);
            jedis.expire(key,(int)((c.getTimeInMillis()-now.getTime()/1000)));
        }else{
            jedis.close();
            return QDResult.fal(505,"");
        }
        jedis.close();
        return QDResult.ok(token,article);
    }

    @Override
    public QDResult delete(BlogArticle blogArticle) {
        return QDResult.ok(mapper.delete(blogArticle));
    }

    @Override
    public QDResult queryByCategoryId(Long id) {
        return QDResult.ok(mapper.queryByCategoryId(id));
    }

    public QDResult update(BlogArticle article, BlogArticleContent content) {
        Jedis jedis = RedisTool.getResource();
        // 清理和文章相关的缓存
        String articleKey = "ARTICLE_9527";
        String artsKey = "ARTICLE_BY_CATID_*"; // *
        Set<String> keys = jedis.keys(artsKey);
        // 清理缓存
        jedis.del(articleKey);// 删除指定的key
        for(String key : keys){
            jedis.del(key);
        }
        jedis.close();// 关闭jedis
        SqlSession sqlSession = MapperFactory.getSqlSession();
        BlogArticleMapper mapper = sqlSession.getMapper(BlogArticleMapper.class);
        try {
            if(mapper.update(article)==1){// 保存article
                // 设置content的id
                content.setArticleId(article.getArticleId());
                // 保存content
                mapper.updateContent(content);
                // 这里保存标签和文章的关系
                // 先删除之前的标签和文章的关系
                mapper.deleteTags(article.getArticleId());
                // 再保存新的标签和文章的关系
                List<BlogTag> tags = article.getTags();
                if(tags!=null && tags.size() > 0){
                    for (BlogTag tag : tags){
                        mapper.saveTagsForArticle(article.getArticleId(),tag.getTagId());
                    }
                }
                // 提交事务
                sqlSession.commit();
                // 开启一个子线程，等待一会删除对应的key。
                Thread t = new Thread(()->{
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Jedis jedis1 = RedisTool.getResource();
                    // 清理和文章相关的缓存
                    String articleKey1 = "ARTICLE_9527";
                    String artsKey1 = "ARTICLE_BY_CATID_*"; // *
                    Set<String> keys1 = jedis.keys(articleKey);
                    // 清理缓存
                    jedis1.del(articleKey1);// 删除指定的key
                    for(String key : keys1){
                        jedis1.del(key);
                    }
                    jedis1.close();// 关闭jedis
                });
                // 将子线程加入线程仓库（理论上使用线程池最好）
                ThreadStorage.addThread(t);
                // 启动子线程
                t.start();
                return QDResult.ok();
            }
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        }finally {
            sqlSession.close();
        }
        return QDResult.fal();
    }


}
